package org.richin.servlet.Filter.util;
import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * {@link Filter} implementation which prevents the session id from being
 * encoded in the URL.
 *
 * @author Niklas Therning
 * @version $Id$
 */
public class DisableSessionIdInUrlFilter implements Filter {
    private static final String SESSION_ID_REG_EXP = "(?i);jsessionid=[0-9a-z]+";
    private static final Pattern SESSION_ID_PATTERN =
        Pattern.compile(SESSION_ID_REG_EXP);

    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        HttpServletRequest newRequest = new RequestWrapper(request);
        HttpServletResponse newResponse = new ResponseWrapper(response);

        chain.doFilter(newRequest, newResponse);
    }

    public void init(FilterConfig fc) throws ServletException {}
    public void destroy() {}

    private static class RequestWrapper extends HttpServletRequestWrapper {
        private String requestUri = null;
        private String requestUrl = null;

        public RequestWrapper(HttpServletRequest request) {
            super(request);
        }
        public boolean isRequestedSessionIdFromURL() {
            return false;
        }
        public boolean isRequestedSessionIdFromUrl() {
            return false;
        }
        public StringBuffer getRequestURL() {
            if (requestUrl == null) {
                requestUrl = removeSessionId(super.getRequestURL().toString());
            }
            return new StringBuffer(requestUrl);
        }
        public String getRequestURI() {
            if (requestUri == null) {
                requestUri = removeSessionId(super.getRequestURI());
            }
            return requestUri;
        }
        private String removeSessionId(String s) {
            return SESSION_ID_PATTERN.matcher(s).replaceFirst("");
        }
    }

    private static class ResponseWrapper extends HttpServletResponseWrapper {

        public ResponseWrapper(HttpServletResponse response) {
            super(response);
        }
        public String encodeRedirectUrl(String url) {
            return url;
        }
        public String encodeRedirectURL(String url) {
            return url;
        }
        public String encodeUrl(String url) {
            return url;
        }
        public String encodeURL(String url) {
            return url;
        }
    }
}
